#include <Windows.h>
#include <commctrl.h>
#include <strsafe.h>

HWND g_myStatic;
HANDLE hOutput;
void consoleInit()
{
    AllocConsole();
    SetConsoleTitle(TEXT("Debug Window"));
    hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
}
void drawRect(HWND hWnd, HBRUSH hBrush)
{
    HDC hdc = GetDC(hWnd);
    RECT rect;
    GetClientRect(hWnd, &rect);
    FillRect(hdc, &rect, hBrush);
}
void drawLine(HWND hWnd, LPARAM lParam)
{
    HDC hdc = GetDC(hWnd);
    //换颜色
    HPEN hPen = CreatePen(PS_SOLID, 5, RGB(255, 255, 255));
    HPEN holdPen = (HPEN)SelectObject(hdc, hPen);
    //画线
    int xPos = LOWORD(lParam);
    int yPos = HIWORD(lParam);
    MoveToEx(hdc, 10, 10, NULL);
    LineTo(hdc, xPos, yPos);
    //还回去
    SelectObject(hdc, holdPen);
}
void drawText(HWND hWnd, LPARAM lParam, BOOL down)
{
    HDC hdc = GetDC(hWnd);
    //画文字
    TCHAR tchar[128] = {0};
    int xPos = down ? LOWORD(lParam) : 10;
    int yPos = down ? HIWORD(lParam) : 10;
    RECT rect = {xPos - 5, yPos - 5, xPos + 100, yPos + 50};
    GetWindowText(hWnd, tchar, 128);
    DrawText(hdc, tchar, lstrlen(tchar), &rect, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS);
}
void btnDown(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HDC hdc = GetDC(hWnd);
    HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
    HBRUSH holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

    drawRect(hWnd, hBrush);
    // InvalidateRect(hWnd, NULL, FALSE);
    drawLine(hWnd, lParam);
    drawText(hWnd, lParam, TRUE);

    SelectObject(hdc, holdBrush);
    DeleteObject(hBrush);
    ReleaseDC(hWnd, hdc);
}
void btnUp(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    HDC hdc = GetDC(hWnd);
    HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
    HBRUSH holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

    drawRect(hWnd, hBrush);
    drawText(hWnd, lParam, FALSE);

    SelectObject(hdc, holdBrush);
    DeleteObject(hBrush);
    ReleaseDC(hWnd, hdc);
}

bool dragMove;
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_CREATE:
    {
    }
    break;
    case WM_PAINT:
    {
        // new test double buffer drawn
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);
        HBRUSH hBrush = CreateSolidBrush(RGB(0, 255, 0));
        HBRUSH holdBrush = (HBRUSH)SelectObject(hdc, hBrush);

        //填充颜色
        RECT rect;
        GetClientRect(hWnd, &rect);
        FillRect(hdc, &rect, hBrush);
        //画文字
        DrawText(hdc, TEXT("hello"), 5, &rect, DT_LEFT | DT_TOP | DT_SINGLELINE | DT_END_ELLIPSIS);

        SelectObject(hdc, holdBrush);
        DeleteObject(hBrush);
        EndPaint(hWnd, &ps);
    }
    break;
    case WM_SIZE:
    {
    }
    break;
    case WM_COMMAND:
    {
    }
    break;
    case WM_LBUTTONDOWN:
    {
        // int xPos = LOWORD(lParam);
        // int yPos = HIWORD(lParam);
        // TCHAR buffer[256];
        // StringCchPrintf(buffer, 256, TEXT("xPos: %d, yPos: %d"), xPos, yPos);
        // MessageBox(hWnd, buffer, TEXT("WM_LBUTTONDOWN"), MB_OK);
        btnDown(hWnd, uMsg, wParam, lParam);
        dragMove = true;
        SetCapture(hWnd);
    }
    break;
    case WM_LBUTTONUP:
    {
        // int xPos = LOWORD(lParam);
        // int yPos = HIWORD(lParam);
        // TCHAR buffer[256];
        // StringCchPrintf(buffer, 256, TEXT("xPos: %d, yPos: %d"), xPos, yPos);
        // MessageBox(hWnd, buffer, TEXT("WM_LBUTTONUP"), MB_OK);
        ReleaseCapture();
        dragMove = false;
        btnUp(hWnd, uMsg, wParam, lParam);
    }
    break;
    case WM_MOUSEMOVE:
    {
        if (dragMove == true)
        {
            btnDown(hWnd, uMsg, wParam, lParam);
        }
    }
    break;
    case WM_KEYDOWN:
    {
    }
    break;
    case WM_CLOSE:
    {
        DestroyWindow(hWnd);
    }
    break;
    case WM_DESTROY:
    {
        PostQuitMessage(0);
    }
    break;
    default:
    {
    }
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

// WINAPI代表__stdcall 参数的传递顺序 从右到左 依次入栈 并且在函数返回前 依次出栈
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    WNDCLASS wc;
    wc.cbClsExtra = 0;                                      // 类的额外内存
    wc.cbWndExtra = 0;                                      // 窗口额外内存
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // 背景
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);               // 光标 第一个为NULL代表使用系统提供的光标
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);             // 图标 第一个为NULL代表使用系统提供的图标
    wc.hInstance = hInstance;                               // 应用程序实例句柄
    wc.lpfnWndProc = WindowProc;                            // 回调函数
    wc.lpszClassName = TEXT("main");                        // 窗口类名称
    wc.lpszMenuName = NULL;                                 // 菜单名称
    wc.style = CS_HREDRAW | CS_VREDRAW;                     // 显示风格

    RegisterClass(&wc);

    /*****
     * CreateWindow()
     * lpClassName,lpWindowName,dwStyle,x,y,nWidth,nHeight,hWndParent,hMenu,hInstance,lpParam
     * 类名
     * 标题名
     * WS_OVERLAPPEDWINDOW 混合风格
     * x坐标 CW_USEDEFAULT
     * y坐标
     * 宽
     * 高
     * 父窗口 NULL
     * 菜单 NULL
     * 实例句柄 hInstance
     * 附加值
     */
    consoleInit();
    HWND hWnd = CreateWindow(wc.lpszClassName, TEXT("Windows"), WS_OVERLAPPEDWINDOW,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             CW_USEDEFAULT,
                             NULL, NULL, hInstance, NULL);
    if (hWnd == NULL)
    {
        return 0;
    }
    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);

    /*****
     * HWND hwnd; 主窗口句柄
     * UINT message; 具体消息名称
     * WPARAM wParam; 附加消息 键盘消息
     * LPARAM lParam; 附加消息 鼠标消息
     * DWORD time; 消息产生时间
     * POINT pt; 附加消息 鼠标消息 x y
     */
    MSG msg;

    /*****
     * LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax
     * 消息
     * 捕获窗口 NULL代表捕获所有窗口
     * 最小的过滤消息 0代表捕获所有消息
     * 最大的过滤消息 0代表捕获所有消息
     */
    while (GetMessage(&msg, NULL, 0, 0))
    {
        // 如果按的是组合键 需要翻译
        TranslateMessage(&msg);
        // 单按一个键盘就直接分发消息
        DispatchMessage(&msg);
    }
    return 0;
}